from django.db import models
from django.contrib.auth.models import AbstractUser
from django.urls import reverse

# Create your models here.

class Menu(models.Model):
    """
    菜单模型
    """
    name = models.CharField(max_length=128, unique=True, verbose_name='菜单名称')
    url = models.CharField(max_length=256, null=True, blank=True, verbose_name='菜单URL')
    icon = models.CharField(max_length=64, null=True, blank=True, verbose_name='图标')
    parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='父菜单')
    order = models.IntegerField(default=0, verbose_name='排序')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')

    class Meta:
        verbose_name = '菜单'
        verbose_name_plural = '菜单'
        ordering = ['order']

    def __str__(self):
        return self.name
    
    def get_full_path(self):
        """
        获取菜单的完整路径（包含所有父级菜单）
        """
        path = [self.name]
        parent = self.parent
        while parent:
            path.insert(0, parent.name)
            parent = parent.parent
        return " > ".join(path)
    
    def get_level(self):
        """
        获取菜单的层级（0表示顶级菜单）
        """
        level = 0
        parent = self.parent
        while parent:
            level += 1
            parent = parent.parent
        return level


class Permission(models.Model):
    """
    权限模型，细化到URL的name属性
    """
    name = models.CharField(max_length=128, unique=True, verbose_name='权限名称')
    url_name = models.CharField(max_length=128, unique=True, verbose_name='URL名称')
    menu = models.ForeignKey(Menu, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='所属菜单')
    description = models.TextField(null=True, blank=True, verbose_name='权限描述')

    class Meta:
        verbose_name = '权限'
        verbose_name_plural = '权限'

    def __str__(self):
        return self.name


class Role(models.Model):
    """
    角色模型
    """
    name = models.CharField(max_length=64, unique=True, verbose_name='角色名称')
    description = models.TextField(null=True, blank=True, verbose_name='角色描述')
    permissions = models.ManyToManyField(Permission, blank=True, verbose_name='权限')
    menus = models.ManyToManyField(Menu, blank=True, verbose_name='菜单')

    class Meta:
        verbose_name = '角色'
        verbose_name_plural = '角色'

    def __str__(self):
        return self.name

    def get_grouped_permissions(self):
        """
        按应用名称分组权限
        """
        permissions = self.permissions.all()
        grouped_permissions = {}
        
        for perm in permissions:
            # 从url_name中提取应用名称
            if ':' in perm.url_name:
                app_name = perm.url_name.split(':')[0]
            else:
                app_name = '通用'
                
            if app_name not in grouped_permissions:
                grouped_permissions[app_name] = []
            grouped_permissions[app_name].append(perm)
        
        return grouped_permissions


class User(AbstractUser):
    """
    用户模型，扩展Django内置的User模型
    """
    nickname = models.CharField(max_length=64, null=True, blank=True, verbose_name='昵称')
    phone = models.CharField(max_length=20, null=True, blank=True, verbose_name='电话')
    email = models.EmailField(null=True, blank=True, verbose_name='邮箱')
    roles = models.ManyToManyField(Role, blank=True, verbose_name='角色')
    avatar = models.ImageField(upload_to='avatars/', null=True, blank=True, verbose_name='头像')

    class Meta:
        verbose_name = '用户'
        verbose_name_plural = '用户'
        ordering = ['id']

    def __str__(self):
        return self.username

    @property
    def full_name(self):
        return f"{self.last_name}{self.first_name}" if self.last_name or self.first_name else self.username

    def get_user_permissions(self):
        """
        获取用户所有权限URL名称
        """
        permissions = set()
        for role in self.roles.all():
            for permission in role.permissions.all():
                permissions.add(permission.url_name)
        return permissions

    def get_user_menus(self):
        """
        获取用户有权访问的菜单
        """
        menus = set()
        for role in self.roles.all():
            for menu in role.menus.all():
                menus.add(menu)
        return menus
    
    def get_user_menu_urls(self):
        """
        获取用户有权访问的菜单URL列表
        """
        menu_urls = set()
        for menu in self.get_user_menus():
            if menu.url:
                menu_urls.add(menu.url)
        return menu_urls
